﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace LogitechLCDWrapper
{
    public class ColorLCDScreen : LCDScreen
    {
        #region DLLImports

        [DllImport(DllPath, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        static extern bool LogiLcdColorSetText(int lineNumber, StringBuilder text, int red, int green, int blue);
        [DllImport(DllPath, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        static extern bool LogiLcdColorSetTitle(StringBuilder text, int red, int green, int blue);
        [DllImport(DllPath, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        static extern bool LogiLcdColorSetBackground(Byte[] colorBitmap);
        #endregion

        List<LCDButtons> _buttons;

        public ColorLCDScreen(string appName)
            : base(appName, LCDType.Color)
        {

        }

        protected override List<LCDButtons> Buttons
        {
            get
            {
                if (_buttons == null)
                {
                    _buttons = new List<LCDButtons>(new List<LCDButtons>(new[] { LCDButtons.ColorCancel, 
                        LCDButtons.ColorDown, 
                        LCDButtons.ColorLeft, 
                        LCDButtons.ColorOk, 
                        LCDButtons.ColorRight,
                        LCDButtons.ColorUp, 
                        LCDButtons.ColorMenu }));
                }
                return _buttons;
            }
        }
        protected override void Initialize()
        {
            ScreenHeight = 240;
            ScreenWidth = 320;
            MaxLines = 8;
            MaxCharPerLine = 28;
            RefreshFrequency = 60;
            BackgroundSize = ScreenSize * 4;
        }

        protected override void DrawBackground(TimeSpan elapsedTime)
        {
            BeginDrawing();
            byte[] bArray = new byte[BackgroundSize];

            for (int y = 0; y < ScreenHeight; y++)
            {
                for (int x = 0; x < ScreenWidth; x++)
                {
                    var col = Background.GetPixel(x, y);
                    bArray[4 * ( x + y * ScreenWidth)] = col.B;
                    bArray[4 * (x + y * ScreenWidth) + 1] = col.G;
                    bArray[4 * (x + y * ScreenWidth) + 2] = col.R;
                    bArray[4 * (x + y * ScreenWidth) + 3] = col.A;
                }
            }
            EndDrawing();
            LogiLcdColorSetBackground(bArray);
        }
        protected override void DrawText(TimeSpan elapsedTime)
        {
            for (int i = 0; i < MaxLines; i++)
            {
                string temp = Lines[i];
                if (EnableTextScrolling && Lines[i].Length > MaxCharPerLine)
                {
                    temp = Lines[i].Substring(scrollIndices[i], MaxCharPerLine + scrollIndices[i] > Lines[i].Length ? Lines[i].Length - scrollIndices[i] : MaxCharPerLine);
                    if (DateTime.Now.Ticks > previousScrollTime[i].Ticks + (TimeSpan.TicksPerSecond * ScrollSpeed))
                    {
                        scrollIndices[i] = scrollIndices[i] + MaxCharPerLine >= Lines[i].Length ? scrollIndices[i] - 1 : scrollIndices[i] + 1 * scrollDirection[i];
                        previousScrollTime[i] = DateTime.Now;
                        scrollDirection[i] = scrollIndices[i] >= Lines[i].Length - MaxCharPerLine ? -1 : scrollIndices[i] == 0 ? 1 : scrollDirection[i];
                    }
                }
                LogiLcdColorSetText(i, new StringBuilder(temp), Pen.Color.R, Pen.Color.G, Pen.Color.B);
            }
        }
        public override bool IsConnected
        {
            get
            {
                return LogiLcdIsConnected((int)LCDType.Color);
            }
        }
        public void DisplayText(string text, int line)
        {
            Lines[line % MaxLines] = text;
            scrollIndices[line % MaxLines] = 1;
        }

        public void SetPixel(double x, double y, System.Drawing.Color color)
        {
            if (x >= 0 && x < ScreenWidth && y >= 0 && y < ScreenHeight)
            {
                BeginDrawing();
                Background.SetPixel(Convert.ToInt32(x), Convert.ToInt32(y), color);
                EndDrawing();
            }
        }

        public void DrawImage(System.Drawing.Bitmap bmp)
        {
            BeginDrawing();
            GraphicDevice.DrawImage(bmp, 0, 0);
            EndDrawing();

        }

        System.Drawing.Pen _pen = new System.Drawing.Pen(System.Drawing.Color.White);
        public System.Drawing.Pen Pen
        {
            get { return _pen; }
            set { _pen = value; }
        }
    }
}
